package com.zxt.dlna.application;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.zxt.dlna.R;
import com.zxt.dlna.activity.device.DeviceListRegistryListener;
import com.zxt.dlna.activity.IndexActivity;
import com.zxt.dlna.dmp.DeviceItem;
import com.zxt.dlna.dmr.ZxtMediaRenderer;
import com.zxt.dlna.dms.ContentTree;
import com.zxt.dlna.util.FileUtil;
import com.zxt.dlna.util.ImageUtil;

import org.fourthline.cling.android.AndroidUpnpService;
import org.fourthline.cling.android.AndroidUpnpServiceImpl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class MyStartService extends Service {
    private final String TAG = "MyStartService";

    public static final int GET_IP_FAIL = 0;

    public static final int GET_IP_SUC = 1;

    private Context mContext;

    private String hostName;

    private String hostAddress;

    private List<Map<String, String>> mVideoFilePaths;

    private final Handler mHandle = new Handler(Looper.getMainLooper()) {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_IP_FAIL: {
                    Toast.makeText(mContext, R.string.ip_get_fail, Toast.LENGTH_SHORT);
                    break;
                }
                case GET_IP_SUC: {
                    if (null != msg.obj) {
                        InetAddress inetAddress = (InetAddress) msg.obj;
                        if (null != inetAddress) {
                            setIp(inetAddress);
                            setIpInfo();
                            jumpToMain();
                        }
                    } else {
                        Toast.makeText(mContext, R.string.ip_get_fail, Toast.LENGTH_SHORT);
                    }
                    break;
                }

            }

            super.handleMessage(msg);
        }

    };


    private void createFolder() {
        FileUtil.createSDCardDir(true);
    }

    private void getIp() {
        new Thread(new Runnable() {

            @SuppressLint("DefaultLocale")
            @Override
            public void run() {
                WifiManager wifiManager = (WifiManager) mContext.getSystemService(WIFI_SERVICE);
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                int ipAddress = wifiInfo.getIpAddress();

                InetAddress inetAddress;
                Message message = new Message();
                try {
                    inetAddress = InetAddress.getByName(String.format("%d.%d.%d.%d",
                            (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
                            (ipAddress >> 24 & 0xff)));

                    hostName = inetAddress.getHostName();
                    hostAddress = inetAddress.getHostAddress();
                    message.obj = inetAddress;
                    message.what = GET_IP_SUC;
                    mHandle.sendMessage(message);
                } catch (UnknownHostException e) {
                    mHandle.sendEmptyMessage(GET_IP_FAIL);
                }
            }
        }).start();

    }

    private void getVideoFilePaths() {
        // 检查是否有读取存储权限
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
                    != android.content.pm.PackageManager.PERMISSION_GRANTED) {
                // 如果没有权限，可以选择跳过或者请求权限（在Service中请求权限比较复杂）
                mVideoFilePaths = new ArrayList<>();
                return;
            }
        }
        mVideoFilePaths = new ArrayList<>();
        Cursor cursor;
        String[] videoColumns = {
                MediaStore.Video.Media._ID, MediaStore.Video.Media.TITLE,
                MediaStore.Video.Media.DATA, MediaStore.Video.Media.ARTIST,
                MediaStore.Video.Media.MIME_TYPE, MediaStore.Video.Media.SIZE,
                MediaStore.Video.Media.DURATION, MediaStore.Video.Media.RESOLUTION
        };
        cursor = mContext.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                videoColumns, null, null, null);
        if (null != cursor && cursor.moveToFirst()) {
            do {
                String id = ContentTree.VIDEO_PREFIX
                        + cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media._ID));
                String filePath = cursor.getString(cursor
                        .getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
                Map<String, String> fileInfoMap = new HashMap<String, String>();
                fileInfoMap.put(id, filePath);
                mVideoFilePaths.add(fileInfoMap);
                // Log.v(TAG, "added video item " + title + "from " +
                // filePath);
            } while (cursor.moveToNext());
        }
        if (null != cursor) {
            cursor.close();
        }

    }

    private void createVideoThumb() {
        // 检查权限
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
                    != android.content.pm.PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "No permission to read external storage, skipping video thumbnail creation");
                return;
            }
        }
        if (null != mVideoFilePaths && !mVideoFilePaths.isEmpty()) {
            new Thread(() -> {
                for (int i = 0; i < mVideoFilePaths.size(); i++) {
                    Set<?> entries = mVideoFilePaths.get(i).entrySet();
                    for (Object o : entries) {
                        Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
                        Object id = entry.getKey();
                        Object filePath = entry.getValue();

                        Bitmap videoThumb = ImageUtil.getThumbnailForVideo(filePath
                                .toString());
                        String videoSavePath = ImageUtil.getSaveVideoFilePath(
                                filePath.toString(), id.toString());
                        try {
                            ImageUtil.saveBitmapWithFilePathSuffix(videoThumb,
                                    videoSavePath);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }

    private void setIp(InetAddress inetAddress) {
        BaseApplication.setLocalIpAddress(inetAddress);
    }

    private void setIpInfo() {
        BaseApplication.setHostName(hostName);
        BaseApplication.setHostAddress(hostAddress);
    }

    private void jumpToMain() {
//        Intent intent = new Intent(StartActivity.this, IndexActivity.class);
//        startActivity(intent);
//        this.finish();
    }

    public MyStartService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "===> onBind: " + this);
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "===> onStartCommand: " + this);
        Intent notificationIntent = new Intent(this, IndexActivity.class); // 或者其他Activity
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("DLNA Service")
                .setContentText("Running")
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1, notification);

        mContext = this;

        init();
        startDevice();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "===> onDestroy:  " + this);
        super.onDestroy();
    }

    private AndroidUpnpService upnpService;
    private DeviceListRegistryListener deviceListRegistryListener;
    private final ArrayList<DeviceItem> mDmrList = new ArrayList<>();

    private boolean getRenderOn(Context context) {
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(context);
        return prefs.getBoolean("dmr_status", true);
    }

    private final ServiceConnection serviceConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder service) {

            mDmrList.clear();

            upnpService = (AndroidUpnpService) service;
            BaseApplication.upnpService = upnpService;
            Log.v(TAG, "Connected to UPnP Service");
            if (getRenderOn(MyStartService.this)) {
                ZxtMediaRenderer mediaRenderer = new ZxtMediaRenderer(1, MyStartService.this);
                upnpService.getRegistry().addDevice(mediaRenderer.getDevice());
                deviceListRegistryListener.dmrAdded(new DeviceItem(mediaRenderer.getDevice()));
            }
            // Getting ready for future device advertisements
            upnpService.getRegistry().addListener(deviceListRegistryListener);
            // Refresh device list
            upnpService.getControlPoint().search();
            if (!mDmrList.isEmpty() && null == BaseApplication.dmrDeviceItem) {
                BaseApplication.dmrDeviceItem = mDmrList.get(0);
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            upnpService = null;
        }
    };

    private void startDevice() {
        deviceListRegistryListener = new DeviceListRegistryListener(mDmrList, null, null, null);

        getApplicationContext().bindService(
                new Intent(this, AndroidUpnpServiceImpl.class),
                serviceConnection, Context.BIND_AUTO_CREATE);
    }

    private void init() {
        createFolder();
        getVideoFilePaths();
        if (mVideoFilePaths != null && !mVideoFilePaths.isEmpty()) {
            createVideoThumb();
        }
        getIp();
    }

}